package com.ssb.util.sign;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * 3DES 算法加解密帮助类
 * @author Administrator
 *
 */
public class TripleDESHelper {
    public static final String CBC = "DESede/CBC/PKCS5Padding";
    private String _Algorithm;
    private IvParameterSpec _IV;
    private SecretKeySpec _Key;

    public TripleDESHelper()
    {
    }
    /**
     * CBC 方式初始化
     * @param keyBase64 秘钥的 base64  方式编码字符串
     * @param ivBase64 初始化向量的 base64 方式编码字符串
     * @throws Exception
     */
    public void initCBC(String keyBase64, String ivBase64)
    {
        initCBC(Base64Helper.decode(keyBase64), Base64Helper.decode(ivBase64));
    }
    /**
     * CBC 方式初始化
     * @param keyBytes 秘钥
     * @param ivBytes  初始化向量
     * @throws Exception
     */
    public void initCBC(byte[] keyBytes, byte[] ivBytes)
    {
        _Algorithm = CBC;
        //_Key = new SecretKeySpec(keyBytes, "DESede");
        _Key = new SecretKeySpec(keyBytes, "TripleDES");
        _IV = new IvParameterSpec(ivBytes);
    }
    /**
     * 将源文件加密保存到目标文件
     * @param sourceFileName
     * @param destFileName
     * @throws IOException
     * @throws InvalidAlgorithmParameterException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public void encrypt(String sourceFileName, String destFileName) throws IOException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException
    {
        byte[] sourceBytes = IOHelper.fileToBytes(sourceFileName);
        byte[] destBytes = encrypt(sourceBytes);
        IOHelper.bytesToFile(destBytes, destFileName);
    }
    /**
     * 将 base64 编码的源数据加密，返回加密后内容的 base64 编码字符串
     * @param sourceBase64
     * @return
     * @throws InvalidAlgorithmParameterException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public String encrypt(String sourceBase64) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException
    {
        byte[] sourceBytes = Base64Helper.decode(sourceBase64);
        byte[] destBytes = encrypt(sourceBytes);
        return Base64Helper.encode(destBytes);
    }
    /**
     * 将源数据加密，返回加密后内容
     * @param source
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws InvalidAlgorithmParameterException
     * @throws InvalidKeyException
     */
    public byte[] encrypt(byte[] source) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidAlgorithmParameterException
    {
        Cipher cipher = Cipher.getInstance(_Algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, _Key, _IV);
        return cipher.doFinal(source);
    }
    /**
     * 将源文件解密保存到目标文件
     * @param sourceFileName
     * @param destFileName
     * @throws IOException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws InvalidAlgorithmParameterException
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public void decrypt(String sourceFileName, String destFileName)
            throws IOException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
    {
        byte[] sourceBytes = IOHelper.fileToBytes(sourceFileName);
        byte[] destBytes = decrypt(sourceBytes);
        IOHelper.bytesToFile(destBytes, destFileName);
    }
    /**
     * 将 base64 编码的源数据解密，返回解密后内容的 base64 编码字符串
     * @param sourceBase64
     * @return
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws InvalidAlgorithmParameterException
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public String decrypt(String sourceBase64)
            throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
    {
        byte[] sourceBytes = Base64Helper.decode(sourceBase64);
        byte[] destBytes = decrypt(sourceBytes);
        return Base64Helper.encode(destBytes);
    }
    /**
     * 将源数据加密，返回解密后内容
     * @param source
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidAlgorithmParameterException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    public byte[] decrypt(byte[] source)
            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
    {
        Cipher cipher = Cipher.getInstance(_Algorithm);
        cipher.init(Cipher.DECRYPT_MODE, _Key, _IV);
        return cipher.doFinal(source);
    }
}

